#include <QFile>
#include <QDir>
#include <QTextDocument>
#include <QTextFormat>
#include <QTextTable>
#include <QTextCursor>
#include <QDomDocument>
#include <QMultiMap>

#include <coveragemodel.h>
#include "coveragemodelhtmladapter.h"

CoverageModelHTMLAdapter::CoverageModelHTMLAdapter(QObject * parent)
    : QObject(parent)
{
}

QString CoverageModelHTMLAdapter::name()const
{
    return "coveragemodelhtmladapter";
}

QString CoverageModelHTMLAdapter::description()const
{
    return tr("This plugin provides workflow coverage HTML reports generation.");
}

bool CoverageModelHTMLAdapter::saveModel(CoverageModel * model, const QDir & dir, const QString & version)
{
    QDateTime versionStartDateTime = QDateTime::fromString(("2011-05-23T00:00:00+01:00"), Qt::ISODate);
    QMultiMap <QString, ARSWorkflowObject *> crMap = createCrMap(model->workflowList(), versionStartDateTime);
    createMainPage(model, dir, versionStartDateTime, crMap);
    createWorkflowPage(model, dir, versionStartDateTime, crMap);
    createHomelessWorkflowPage(model, dir, versionStartDateTime, crMap);
    createTestcaseDetailsPage(model, dir, versionStartDateTime, crMap);

    return true;
}

QMultiMap <QString, ARSWorkflowObject *> CoverageModelHTMLAdapter::createCrMap(const ARSWorkflowObjectList & list,
                                                                               const QDateTime & versionStartDate)
{
    QMultiMap <QString, ARSWorkflowObject *> map;
    foreach(ARSWorkflowObject * object, list)
    {
        QStringList crs = relatedCRs(object->changeHistory(), versionStartDate);
        foreach(QString cr, crs)
        {
            if(!map.contains(cr, object))
                map.insertMulti(cr, object);
        }
    }

    return map;
}

bool CoverageModelHTMLAdapter::createMainPage(CoverageModel * model, const QDir & dir, const QDateTime & versionStartDateTime, const QMultiMap <QString, ARSWorkflowObject *> & crMap)
{
    QFile outFile(dir.filePath("summary.html"));
    if(!outFile.open(QIODevice::WriteOnly))
        return false;

    QTextDocument document;
    document.setDocumentMargin(100);
    QTextCursor textCursor(&document);

    QTextFrameFormat frameFormat;
    frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
    frameFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100));
    frameFormat.setPadding(0);
    frameFormat.setBottomMargin(30);
    frameFormat.setBackground(QColor(0x655095));
    textCursor.insertFrame(frameFormat);

    QTextCharFormat aboutTextFormat;
    QFont aboutTextFont("Courier New", 10);
    aboutTextFormat.setFont(aboutTextFont);
    aboutTextFormat.setForeground(Qt::white);

    textCursor.insertText(tr("Generated by ARS Illustrator"), aboutTextFormat);

    textCursor.movePosition(QTextCursor::End);

    QFont titleFont("Calibri", 18);
    titleFont.setBold(true);
    QTextCharFormat titleFormat;
    titleFormat.setFont(titleFont);
    textCursor.setBlockCharFormat(titleFormat);
    textCursor.insertText(tr("Summary"));

    frameFormat.setTopMargin(30);
    frameFormat.setBottomMargin(30);
    frameFormat.setBackground(QColor(0xf0f0f0));
    frameFormat.setPadding(10);
    textCursor.insertFrame(frameFormat);
    textCursor.insertHtml("<a href=\"crdetails.html\">CR Details</a>");
    textCursor.movePosition(QTextCursor::End);
    frameFormat.setTopMargin(0);
    textCursor.insertFrame(frameFormat);
    textCursor.insertHtml("<a href=\"homelessworkflow.html\">Homeless Workflow</a>");
    textCursor.movePosition(QTextCursor::End);

    QTextCharFormat textFormat;
    QFont textFont("Calibri", 11);
    textFormat.setFont(textFont);
    textFormat.setForeground(Qt::black);

    QTextCharFormat headerFormat;
    QFont headerFont = textFont;
    headerFormat.setFont(headerFont);
    headerFormat.setForeground(Qt::white);

    QTextTableCellFormat headerCellFormat;
    headerCellFormat.setBackground(QColor(0x655095));

    QTextTable * summaryTable = textCursor.insertTable(3, 2);
    QTextTableFormat summaryTableFormat;
    summaryTableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
    summaryTableFormat.setCellPadding(4);
    summaryTable->setFormat(summaryTableFormat);

    QTextCharFormat summaryTextFormat;
    QFont summaryTextFont("Calibri", 12);
    summaryTextFormat.setFont(summaryTextFont);
    summaryTextFormat.setForeground(Qt::black);

    QTextCharFormat summaryHeaderFormat;
    QFont summaryHeaderFont = summaryTextFont;
    summaryHeaderFormat.setFont(summaryHeaderFont);
    summaryHeaderFormat.setForeground(Qt::white);

    QTextTableCellFormat cellFormat;
    cellFormat.setBackground(QColor(0xf8f8ff));

    QTextTableCellFormat evenCellFormat;
    evenCellFormat.setBackground(QColor(0xf0f0ff));

    textCursor = summaryTable->cellAt(0, 0).firstCursorPosition();
    textCursor.insertText("Total objects:", summaryHeaderFormat);
    textCursor = summaryTable->cellAt(0, 1).firstCursorPosition();
    textCursor.insertText(QString::number(model->totalObjectsCount()), summaryTextFormat);
    textCursor = summaryTable->cellAt(1, 0).firstCursorPosition();
    textCursor.insertText("Covered objects:", summaryHeaderFormat);
    textCursor = summaryTable->cellAt(1, 1).firstCursorPosition();
    textCursor.insertText(QString::number(model->coveredObjectsCount()), summaryTextFormat);
    textCursor = summaryTable->cellAt(2, 0).firstCursorPosition();
    textCursor.insertText("Coverage:", summaryHeaderFormat);
    textCursor = summaryTable->cellAt(2, 1).firstCursorPosition();
    textCursor.insertText(QString::number((int)(model->coverage() * 100)) + "%", summaryTextFormat);
    textCursor.movePosition(QTextCursor::End);

    summaryTable->cellAt(0, 0).setFormat(headerCellFormat);
    summaryTable->cellAt(1, 0).setFormat(headerCellFormat);
    summaryTable->cellAt(2, 0).setFormat(headerCellFormat);
    summaryTable->cellAt(0, 1).setFormat(cellFormat);
    summaryTable->cellAt(1, 1).setFormat(evenCellFormat);
    summaryTable->cellAt(2, 1).setFormat(cellFormat);

    QStringList crList = crMap.uniqueKeys();

    QTextTable * textTable = textCursor.insertTable(crList.count() + 1, 3);
    QTextTableFormat tableFormat;
    tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
    tableFormat.setBorderBrush(Qt::white);
    tableFormat.setCellPadding(4);
    tableFormat.setTopMargin(30);
    textTable->setFormat(tableFormat);

    textTable->cellAt(0, 0).setFormat(headerCellFormat);
    textTable->cellAt(0, 1).setFormat(headerCellFormat);
    textTable->cellAt(0, 2).setFormat(headerCellFormat);

    QTextCharFormat poorCoverageFormat;
    poorCoverageFormat.setFont(textFont);
    poorCoverageFormat.setForeground(QColor(200, 50, 50));

    QTextCharFormat averageCoverageFormat;
    averageCoverageFormat.setFont(textFont);
    averageCoverageFormat.setForeground(QColor(150, 150, 50));

    QTextCharFormat totalCoverageFormat;
    totalCoverageFormat.setFont(textFont);
    totalCoverageFormat.setForeground(QColor(50, 150, 50));

    textCursor = textTable->cellAt(0, 0).firstCursorPosition();
    textCursor.insertText(tr("CR"), headerFormat);

    textCursor = textTable->cellAt(0, 1).firstCursorPosition();
    textCursor.insertText(tr("Objects Count"), headerFormat);

    textCursor = textTable->cellAt(0, 2).firstCursorPosition();
    textCursor.insertText(tr("Coverage (%)"), headerFormat);

    for(int i = 0; i < crList.count(); i++)
    {
        textCursor = textTable->cellAt(i + 1, 0).firstCursorPosition();
        textCursor.insertText(crList.at(i), textFormat);

        textCursor = textTable->cellAt(i + 1, 1).firstCursorPosition();
        textCursor.insertText(QString::number(crMap.values(crList.at(i)).count()), textFormat);

        textCursor = textTable->cellAt(i + 1, 2).firstCursorPosition();
        int coverage = model->coverage(crMap.values(crList.at(i))) * 100;
        QTextCharFormat coverageFormat;
        if(coverage < 50)
            coverageFormat = poorCoverageFormat;
        else
            if(coverage < 100)
                coverageFormat = averageCoverageFormat;
            else
                coverageFormat = totalCoverageFormat;

        textCursor.insertText(QString::number(coverage), coverageFormat);

        if(i%2)
        {
             textTable->cellAt(i + 1, 0).setFormat(cellFormat);
             textTable->cellAt(i + 1, 1).setFormat(cellFormat);
             textTable->cellAt(i + 1, 2).setFormat(cellFormat);
        }
        else
        {
            textTable->cellAt(i + 1, 0).setFormat(evenCellFormat);
            textTable->cellAt(i + 1, 1).setFormat(evenCellFormat);
            textTable->cellAt(i + 1, 2).setFormat(evenCellFormat);
        }
    }

    outFile.write(attachCSS(document.toHtml()).toAscii());
    outFile.close();

    return true;
}

bool CoverageModelHTMLAdapter::createWorkflowPage(CoverageModel * model, const QDir & dir, const QDateTime & versionStartDateTime, const QMultiMap <QString, ARSWorkflowObject *> & crMap)
{
    QFile outFile(dir.filePath("crdetails.html"));
    if(!outFile.open(QIODevice::WriteOnly))
        return false;

    QTextDocument document;
    document.setDocumentMargin(100);
    QTextCursor textCursor(&document);

    QTextFrameFormat frameFormat;
    frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
    frameFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100));
    frameFormat.setPadding(0);
    frameFormat.setBottomMargin(30);
    frameFormat.setBackground(QColor(0x655095));
    textCursor.insertFrame(frameFormat);

    QTextCharFormat aboutTextFormat;
    QFont aboutTextFont("Courier New", 10);
    aboutTextFormat.setFont(aboutTextFont);
    aboutTextFormat.setForeground(Qt::white);
    textCursor.insertText(QObject::tr("Generated by ARS Illustrator"), aboutTextFormat);

    QTextCharFormat textFormat;
    QFont textFont("Calibri", 11);
    textFormat.setFont(textFont);
    textFormat.setForeground(Qt::black);
    textCursor.setBlockCharFormat(textFormat);

    textCursor.movePosition(QTextCursor::End);

    QFont titleFont("Calibri", 18);
    titleFont.setBold(true);
    QTextCharFormat titleFormat;
    titleFormat.setFont(titleFont);
    textCursor.setBlockCharFormat(titleFormat);
    textCursor.insertText(tr("CR Details"));

    frameFormat.setTopMargin(30);
    frameFormat.setBackground(QColor(0xf0f0f0));
    frameFormat.setPadding(10);
    textCursor.insertFrame(frameFormat);
    textCursor.insertHtml("<a href=\"summary.html\">Summary</a>");
    textCursor.insertText(" ");
    textCursor.insertHtml("<a href=\"homelessworkflow.html\">Homeless Workflow</a>");
    textCursor.movePosition(QTextCursor::End);

    ARSWorkflowObjectList list = model->workflowList();
    WorkflowCoverageMap coverageMap = model->coverageMap();
    QTextTable * textTable = textCursor.insertTable(list.count() + 100, 4);
    QTextTableFormat tableFormat;
    tableFormat.setCellPadding(4);
    textTable->setFormat(tableFormat);

    QTextCharFormat propertyLabelFormat;
    QFont propertyLablelFont = textFont;
    propertyLabelFormat.setFont(propertyLablelFont);
    propertyLabelFormat.setForeground(Qt::white);

    QTextCursor cellCursor = textTable->cellAt(0, 0).firstCursorPosition();
    cellCursor.insertText("CR", propertyLabelFormat);
    cellCursor = textTable->cellAt(0, 1).firstCursorPosition();
    cellCursor.insertText("Type", propertyLabelFormat);
    cellCursor = textTable->cellAt(0, 2).firstCursorPosition();
    cellCursor.insertText("Name", propertyLabelFormat);
    cellCursor = textTable->cellAt(0, 3).firstCursorPosition();
    cellCursor.insertText("Related Tests", propertyLabelFormat);

    QTextTableCellFormat headerCellFormat;
    headerCellFormat.setBackground(QColor(0x655095));

    textTable->cellAt(0, 0).setFormat(headerCellFormat);
    textTable->cellAt(0, 1).setFormat(headerCellFormat);
    textTable->cellAt(0, 2).setFormat(headerCellFormat);
    textTable->cellAt(0, 3).setFormat(headerCellFormat);

    QTextTableCellFormat cellFormat;
    cellFormat.setBackground(QColor(0xf8f8ff));

    QTextTableCellFormat evenCellFormat;
    evenCellFormat.setBackground(QColor(0xf0f0ff));

    QFont coverageFont = textFont;
    QTextCharFormat coveredFormat;
    coveredFormat.setFont(coverageFont);
    coveredFormat.setForeground(QColor(50, 100, 0));

    QTextCharFormat notCoveredFormat;
    notCoveredFormat.setFont(coverageFont);
    notCoveredFormat.setForeground(QColor(200, 0, 0));

    QStringList crList = crMap.uniqueKeys();
    int row = 1;
    int crStartRow;
    int crRowNum = 1;
    foreach(QString cr, crList)
    {
        crStartRow = row;
        foreach(ARSWorkflowObject * object, crMap.values(cr))
        {
            cellCursor = textTable->cellAt(row, 1).firstCursorPosition();
            if(object->type() == ARSObject::ActiveLink)
                cellCursor.insertText("AL", textFormat);
            else
                cellCursor.insertText("Filter", textFormat);

            cellCursor = textTable->cellAt(row, 2).firstCursorPosition();
            cellCursor.insertText(object->name(), textFormat);
            cellCursor = textTable->cellAt(row, 3).firstCursorPosition();
            QList<const DynamicModel*> modelList = coverageMap.values(object);
            if(modelList.isEmpty())
                cellCursor.insertText("none", notCoveredFormat);
            else
            {
                QString modelsListString;
                foreach(const DynamicModel * dynamicModel, modelList)
                    modelsListString += dynamicModel->sourceName() + "\n";

                cellCursor.insertText(modelsListString, coveredFormat);
            }

            if(crRowNum%2)
            {
                 textTable->cellAt(row, 0).setFormat(cellFormat);
                 textTable->cellAt(row, 1).setFormat(cellFormat);
                 textTable->cellAt(row, 2).setFormat(cellFormat);
                 textTable->cellAt(row, 3).setFormat(cellFormat);
            }
            else
            {
                textTable->cellAt(row, 0).setFormat(evenCellFormat);
                textTable->cellAt(row, 1).setFormat(evenCellFormat);
                textTable->cellAt(row, 2).setFormat(evenCellFormat);
                textTable->cellAt(row, 3).setFormat(evenCellFormat);
            }
            row++;
        }

        textTable->mergeCells(crStartRow, 0, row - crStartRow, 1);
        cellCursor = textTable->cellAt(row - 1, 0).firstCursorPosition();
        cellCursor.insertText(cr, textFormat);
        crRowNum++;
    }

    outFile.write(attachCSS(document.toHtml()).toAscii());
    outFile.close();

    return true;
}

bool CoverageModelHTMLAdapter::createHomelessWorkflowPage(CoverageModel * model, const QDir & dir, const QDateTime & versionStartDateTime, const QMultiMap <QString, ARSWorkflowObject *> & crMap)
{
    QFile outFile(dir.filePath("homelessworkflow.html"));
    if(!outFile.open(QIODevice::WriteOnly))
        return false;

    QTextDocument document;
    document.setDocumentMargin(100);
    QTextCursor textCursor(&document);

    QTextFrameFormat frameFormat;
    frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
    frameFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100));
    frameFormat.setPadding(0);
    frameFormat.setBottomMargin(30);
    frameFormat.setBackground(QColor(0x655095));
    textCursor.insertFrame(frameFormat);

    QTextCharFormat aboutTextFormat;
    QFont aboutTextFont("Courier New", 10);
    aboutTextFormat.setFont(aboutTextFont);
    aboutTextFormat.setForeground(Qt::white);
    textCursor.insertText(QObject::tr("Generated by ARS Illustrator"), aboutTextFormat);

    QTextCharFormat textFormat;
    QFont textFont("Calibri", 11);
    textFormat.setFont(textFont);
    textFormat.setForeground(Qt::black);
    textCursor.setBlockCharFormat(textFormat);

    textCursor.movePosition(QTextCursor::End);

    QFont titleFont("Calibri", 18);
    titleFont.setBold(true);
    QTextCharFormat titleFormat;
    titleFormat.setFont(titleFont);
    textCursor.setBlockCharFormat(titleFormat);
    textCursor.insertText(tr("Homeless Workflow"));

    frameFormat.setTopMargin(30);
    frameFormat.setBackground(QColor(0xf0f0f0));
    frameFormat.setPadding(10);
    textCursor.insertFrame(frameFormat);
    textCursor.insertHtml("<a href=\"summary.html\">Summary</a>");
    textCursor.insertText(" ");
    textCursor.insertHtml("<a href=\"crdetails.html\">CR Details</a>");
    textCursor.movePosition(QTextCursor::End);

    ARSWorkflowObjectList list = createHomelessObjectsList(model->workflowList(), crMap);
    WorkflowCoverageMap coverageMap = model->coverageMap();

    QTextTable * textTable = textCursor.insertTable(list.count() + 1, 3);
    QTextTableFormat tableFormat;
    tableFormat.setCellPadding(4);
    textTable->setFormat(tableFormat);

    QTextCharFormat propertyLabelFormat;
    QFont propertyLablelFont = textFont;
    propertyLabelFormat.setFont(propertyLablelFont);
    propertyLabelFormat.setForeground(Qt::white);

    QTextCursor cellCursor = textTable->cellAt(0, 0).firstCursorPosition();
    cellCursor.insertText("Type", propertyLabelFormat);
    cellCursor = textTable->cellAt(0, 1).firstCursorPosition();
    cellCursor.insertText("Name", propertyLabelFormat);
    cellCursor = textTable->cellAt(0, 2).firstCursorPosition();
    cellCursor.insertText("Related Tests", propertyLabelFormat);

    QTextTableCellFormat headerCellFormat;
    headerCellFormat.setBackground(QColor(0x655095));

    textTable->cellAt(0, 0).setFormat(headerCellFormat);
    textTable->cellAt(0, 1).setFormat(headerCellFormat);
    textTable->cellAt(0, 2).setFormat(headerCellFormat);

    QTextTableCellFormat cellFormat;
    cellFormat.setBackground(QColor(0xf8f8ff));

    QTextTableCellFormat evenCellFormat;
    evenCellFormat.setBackground(QColor(0xf0f0ff));

    QFont coverageFont = textFont;
    QTextCharFormat coveredFormat;
    coveredFormat.setFont(coverageFont);
    coveredFormat.setForeground(QColor(50, 100, 0));

    QTextCharFormat notCoveredFormat;
    notCoveredFormat.setFont(coverageFont);
    notCoveredFormat.setForeground(QColor(200, 0, 0));

    int row = 1;
    foreach(ARSWorkflowObject * object, list)
    {
        cellCursor = textTable->cellAt(row, 0).firstCursorPosition();
        if(object->type() == ARSObject::ActiveLink)
            cellCursor.insertText("AL", textFormat);
        else
            cellCursor.insertText("Filter", textFormat);

        cellCursor = textTable->cellAt(row, 1).firstCursorPosition();
        cellCursor.insertText(object->name(), textFormat);
        cellCursor = textTable->cellAt(row, 2).firstCursorPosition();
        QList<const DynamicModel*> modelList = coverageMap.values(object);
        if(modelList.isEmpty())
            cellCursor.insertText("none", notCoveredFormat);
        else
        {
            QString modelsListString;
            foreach(const DynamicModel * dynamicModel, modelList)
                modelsListString += dynamicModel->sourceName() + "\n";

            cellCursor.insertText(modelsListString, coveredFormat);
        }

        if(row%2)
        {
             textTable->cellAt(row, 0).setFormat(cellFormat);
             textTable->cellAt(row, 1).setFormat(cellFormat);
             textTable->cellAt(row, 2).setFormat(cellFormat);
        }
        else
        {
            textTable->cellAt(row, 0).setFormat(evenCellFormat);
            textTable->cellAt(row, 1).setFormat(evenCellFormat);
            textTable->cellAt(row, 2).setFormat(evenCellFormat);
        }

        row++;
    }

    outFile.write(attachCSS(document.toHtml()).toAscii());
    outFile.close();

    return true;
}

bool CoverageModelHTMLAdapter::createTestcaseDetailsPage(CoverageModel * model, const QDir & dir, const QDateTime & versionStartDateTime, const QMultiMap <QString, ARSWorkflowObject *> & crMap)
{
    QFile outFile(dir.filePath("testcasedetails.html"));
    if(!outFile.open(QIODevice::WriteOnly))
        return false;

    QTextDocument document;
    document.setDocumentMargin(100);
    QTextCursor textCursor(&document);

    QTextFrameFormat frameFormat;
    frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
    frameFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100));
    frameFormat.setPadding(0);
    frameFormat.setBottomMargin(30);
    frameFormat.setBackground(QColor(0x655095));
    textCursor.insertFrame(frameFormat);

    QTextCharFormat aboutTextFormat;
    QFont aboutTextFont("Courier New", 10);
    aboutTextFormat.setFont(aboutTextFont);
    aboutTextFormat.setForeground(Qt::white);
    textCursor.insertText(QObject::tr("Generated by ARS Illustrator"), aboutTextFormat);

    QTextCharFormat textFormat;
    QFont textFont("Calibri", 11);
    textFormat.setFont(textFont);
    textFormat.setForeground(Qt::black);
    textCursor.setBlockCharFormat(textFormat);

    textCursor.movePosition(QTextCursor::End);

    QFont titleFont("Calibri", 18);
    titleFont.setBold(true);
    QTextCharFormat titleFormat;
    titleFormat.setFont(titleFont);
    textCursor.setBlockCharFormat(titleFormat);
    textCursor.insertText(tr("Testcase Details"));
    textCursor.movePosition(QTextCursor::End);

    frameFormat.setTopMargin(30);
    frameFormat.setBackground(QColor(0xf0f0f0));
    textCursor.insertFrame(frameFormat);
    textCursor.movePosition(QTextCursor::End);

    textCursor.insertHtml("<a href=\"summary.html\">Summary</a>");
    textCursor.insertHtml("<a href=\"crdetails.html\">CR Details</a>");
    textCursor.insertHtml("<a href=\"homelessworkflow.html\">Homeless Workflow</a>");
    textCursor.movePosition(QTextCursor::End);

    WorkflowCoverageMap coverageMap = model->coverageMap();
    QStringList testCaseList = createTestcaseList(model->dynamicModelsList());

    QTextTable * textTable = textCursor.insertTable(1000, 2);
    QTextTableFormat tableFormat;
    tableFormat.setCellPadding(4);
    textTable->setFormat(tableFormat);

    QTextCharFormat propertyLabelFormat;
    QFont propertyLablelFont = textFont;
    propertyLabelFormat.setFont(propertyLablelFont);
    propertyLabelFormat.setForeground(Qt::white);

    QTextCursor cellCursor = textTable->cellAt(0, 0).firstCursorPosition();
    cellCursor.insertText("Test Case", propertyLabelFormat);
    cellCursor = textTable->cellAt(0, 1).firstCursorPosition();
    cellCursor.insertText("Related Objects", propertyLabelFormat);

    QTextTableCellFormat headerCellFormat;
    headerCellFormat.setBackground(QColor(0x655095));

    textTable->cellAt(0, 0).setFormat(headerCellFormat);
    textTable->cellAt(0, 1).setFormat(headerCellFormat);

    QTextTableCellFormat cellFormat;
    cellFormat.setBackground(QColor(0xf8f8ff));

    QTextTableCellFormat evenCellFormat;
    evenCellFormat.setBackground(QColor(0xf0f0ff));

    QMultiMap<QString, ARSWorkflowObject *> testObjectMap = createTestObjectMap(coverageMap, testCaseList);
    int row = 1;
    foreach(QString testCase, testCaseList)
    {
        cellCursor = textTable->cellAt(row, 0).firstCursorPosition();
        cellCursor.insertText(testCase, textFormat);

        ARSWorkflowObjectList objectsList = testObjectMap.values(testCase);

        foreach(ARSWorkflowObject * workflowObject, objectsList)
        {
            cellCursor = textTable->cellAt(row, 1).firstCursorPosition();
            cellCursor.insertText(workflowObject->name(), textFormat);

            if(row%2)
            {
                 textTable->cellAt(row, 0).setFormat(cellFormat);
                 textTable->cellAt(row, 1).setFormat(cellFormat);
            }
            else
            {
                textTable->cellAt(row, 0).setFormat(evenCellFormat);
                textTable->cellAt(row, 1).setFormat(evenCellFormat);
            }

            row++;
        }

        if(objectsList.isEmpty())
            row++;
    }

    outFile.write(attachCSS(document.toHtml()).toAscii());
    outFile.close();

    return true;
}

ARSWorkflowObjectList CoverageModelHTMLAdapter::createHomelessObjectsList(const ARSWorkflowObjectList & list, QMultiMap <QString, ARSWorkflowObject *> crMap)
{
    ARSWorkflowObjectList resultList;
    ARSWorkflowObjectList crRelatedobjects = crMap.values();
    foreach(ARSWorkflowObject * object, list)
    {
        if(!crRelatedobjects.contains(object))
            resultList.append(object);
    }

    return resultList;
}

QStringList CoverageModelHTMLAdapter::createTestcaseList(const QList<const DynamicModel *> & modelList)
{
    QStringList testCaseList;
    foreach(const DynamicModel * model, modelList)
    {
        if(!testCaseList.contains(model->sourceName()))
            testCaseList.append(model->sourceName());
    }

    return testCaseList;
}

QMultiMap<QString, ARSWorkflowObject *> CoverageModelHTMLAdapter::createTestObjectMap(const WorkflowCoverageMap & coverageMap, QStringList testcaseList) const
{
    QMultiMap<QString, ARSWorkflowObject *> resultMap;

    foreach(QString testCase, testcaseList)
    {
        foreach(const DynamicModel * dynamicModel, coverageMap.values())
        {
            if(dynamicModel->sourceName() == testCase)
            {
                foreach(ARSWorkflowObject * workflowObject, coverageMap.keys(dynamicModel))
                {
                    if(!resultMap.contains(testCase, workflowObject))
                        resultMap.insertMulti(testCase, workflowObject);
                }
            }
        }
    }

    return resultMap;
}

QStringList CoverageModelHTMLAdapter::relatedCRs(const QStringList & changeHistory, const QDateTime & versionStartDateTime) const
{
    QStringList crList;

    foreach(QString entry, changeHistory)
    {
        QString modifiedDateStr = entry.left(QString("2009-12-02T14:30:42+01:00").length());
        QDateTime modifiedDateTime = QDateTime::fromString(modifiedDateStr, Qt::ISODate);
        if(modifiedDateTime.isValid() && (modifiedDateTime > versionStartDateTime))
        {
            int index = entry.indexOf(QRegExp("\\d\\d\\d\\d\\d"));
            if(index != -1)
                crList += entry.mid(index, 5);
        }
    }

    return crList;
}

QString CoverageModelHTMLAdapter::attachCSS( const QString & html )
{
    QString htmlString = html;
    QString cssString = "table, td, th\n"\
    "{\n"\
    "border:1px solid #DDDDEE;\n"\
    "border-collapse: collapse;\n"\
    "}\n"\
    "th\n"\
    "{\n"\
    "background-color:green;\n"\
    "color:white;\n"\
    "}\n";
    int index = htmlString.indexOf("</style>");
    if(index != -1)
        htmlString.insert(index, cssString);

    return htmlString;
}


